package agorithm.week2.classOne;

import java.util.HashSet;
import java.util.Set;

/**
 * 874. 模拟行走机器人
 * 机器人在一个无限大小的 XY 网格平面上行走，从点 (0, 0) 处开始出发，面向北方。该机器人可以接收以下三种类型的命令 commands ：
 * <p>
 * -2 ：向左转 90 度
 * -1 ：向右转 90 度
 * 1 <= x <= 9 ：向前移动 x 个单位长度
 * 在网格上有一些格子被视为障碍物 obstacles 。第 i 个障碍物位于网格点  obstacles[i] = (xi, yi) 。
 * <p>
 * 机器人无法走到障碍物上，它将会停留在障碍物的前一个网格方块上，但仍然可以继续尝试进行该路线的其余部分。
 * <p>
 * 返回从原点到机器人所有经过的路径点（坐标为整数）的最大欧式距离的平方。（即，如果距离为 5 ，则返回 25 ）
 * <p>
 * <p>
 * 注意：
 * <p>
 * 北表示 +Y 方向。
 * 东表示 +X 方向。
 * 南表示 -Y 方向。
 * 西表示 -X 方向。
 * <p>
 * <p>
 * 示例 1：
 * <p>
 * 输入：commands = [4,-1,3], obstacles = []
 * 输出：25
 * 解释：
 * 机器人开始位于 (0, 0)：
 * 1. 向北移动 4 个单位，到达 (0, 4)
 * 2. 右转
 * 3. 向东移动 3 个单位，到达 (3, 4)
 * 距离原点最远的是 (3, 4) ，距离为 32 + 42 = 25
 * 示例 2：
 * <p>
 * 输入：commands = [4,-1,4,-2,4], obstacles = [[2,4]]
 * 输出：65
 * 解释：机器人开始位于 (0, 0)：
 * 1. 向北移动 4 个单位，到达 (0, 4)
 * 2. 右转
 * 3. 向东移动 1 个单位，然后被位于 (2, 4) 的障碍物阻挡，机器人停在 (1, 4)
 * 4. 左转
 * 5. 向北走 4 个单位，到达 (1, 8)
 * 距离原点最远的是 (1, 8) ，距离为 12 + 82 = 65
 * <p>
 * <p>
 * 提示：
 * <p>
 * 1 <= commands.length <= 104
 * commands[i] is one of the values in the list [-2,-1,1,2,3,4,5,6,7,8,9].
 * 0 <= obstacles.length <= 104
 * -3 * 104 <= xi, yi <= 3 * 104
 * 答案保证小于 231
 */
public class RobotSim {
    public static void main(String[] args) {
        int[] commands = {-2, 8, 3, 7, -1};
        int[][] obstacles = {{-4, -1}, {1, -1}, {1, 4}, {5, 0}, {4, 5}, {-2, -1}, {2, -5}, {5, 1}, {-3, -1}, {5, -3}};
        System.out.println(robotSim(commands, obstacles));
    }

    /**
     * 遍历指令
     * 障碍物节点放入set
     *
     * @param commands
     * @param obstacles
     * @return
     */
    public static int robotSim(int[] commands, int[][] obstacles) {

        //            N W S  E
        int[] plus = {0, 1, 0, -1};
        int[] mid = {1, 0, -1, 0};
        // 一个Set存放障碍物节点
//        Set<String> s = new HashSet<>();
        Set<Long> s = new HashSet<>();
        for (int i = 0; i < obstacles.length; i++) {
            s.add(hashKey(obstacles[i][0], obstacles[i][1]));
        }
        // 记录的结果最大值
        int max = 0;
        //初始x,y
        int x = 0;
        int y = 0;
        // 执行指向方向，起始方向为北方
        int index = 0;
        // 便利指令
        for (int i = 0; i < commands.length; i++) {

            int num = commands[i];
            if (num == -1) {
                index = (index + 1) % 4;
            } else if (num == -2) {
                // +4 是为了防止index = 0的时候越界
                index = (index + 4 - 1) % 4;
            } else {
                for (int j = 0; j < num; j++) {
                    //  System.out.println("x="+x+";y="+y+"key="+s.contains(hashKey(x+plus[index],y+mid[index]))+",index="+index+"x+1="+(x+plus[index])+";y+1="+(y+mid[index]));
                    if (s.contains(hashKey(x + plus[index], y + mid[index]))) {
                        break;
                    }
                    x += plus[index];
                    y += mid[index];
                    int l = x * x + y * y;
                    max = max > l ? max : l;
                }
            }
        }
        return max;
    }

    private static long hashKey(int x, int y) {
        // return x + "," + y;
        return (x + 30000) * 30000 + y + 30000;
    }
}
